use std::io;

/** # 整数组合
编写一个程序，实现以下功能：
- 提示用户输入任意10个整数；
- 穷举这10个整数中，任意两个数字的所有可能的组合。*/
pub fn int_combination() {
    let int_c = IntCombination::build();
    int_c.exhaustive_combination();
}

#[derive(Debug)]
struct IntCombination {
    integers: Vec<i32>,
}

impl IntCombination {
    /** ## 构造函数
    - 请求用户输入数值
    - 导出结构体 */
    pub fn build() -> Self {
        let mut integers: Vec<i32> = Vec::new();
        // 给予用户一个提示
        println!("请输入任意10组整数（单次输入按Enter键结束）：");

        // 循环10次，获取用户输入
        for i in 1..=10 {
            // 每次循环将用户输入的值传给整数集
            integers.push(get_user_input(i));
        }
        Self { integers }
    }

    /** 穷举组合
    - 穷举10个整数中任意两种数字的组合方式 */
    pub fn exhaustive_combination(&self) {
        let mut exhaustive: Vec<(i32, i32)> = vec![];

        // 第一遍循环：从0~底循环 integers 数组
        for i in 0..self.integers.len() {
            let start_index = i + 1;

            // 当起始索引小于数组最大长度时，从起始索引开始第二次循环integers数组
            if start_index < self.integers.len() {
                for j in (i + 1)..self.integers.len() {
                    exhaustive.push((self.integers[i], self.integers[j]));
                }
            }
        }

        // 打印穷举结果
        println!("两个数的所有组合：{:?}", exhaustive);
    }
}

/** ## 获取用户输入
- 获取用户在命令行中输入的内容
- 判断输入结果是否符合期望值：
   - 如果符合：返回用户输入的值
   - 如不符合：递归调用当前函数，由用户重新输入
*/
fn get_user_input(i: i32) -> i32 {
    println!("请输入第 {i} 个整数：");
    let mut input = String::new();

    // 采集用户在命令行中输入的内容
    io::stdin().read_line(&mut input).expect("读取失败");

    match input.trim().parse::<i32>() {
        // 成功时，将当前值返回出去
        Ok(res) => res,

        // 错误时，提示用户重新输入并递归当前函数重新获取用户输入
        Err(_e) => {
            println!("请输入正确的整数！{}", _e);
            get_user_input(i)
        }
    }
}
